﻿//#include<iostream>
//#include<vector>
//using namespace std;
//struct Point
//{
//	int _x;
//	int _y;
//};
//class Date
//{
//public:
//	Date(int year = 1, int month = 1, int day = 1)
//		:_year(year)
//		, _month(month)
//		, _day(day)
//	{
//		cout << "Date(int year, int month, int day)" << endl;
//	}
//	Date(const Date& d)
//		:_year(d._year)
//		, _month(d._month)
//		, _day(d._day)
//	{
//		cout << "Date(const Date& d)" << endl;
//	}
//private:
//	int _year;
//	int _month;
//	int _day;
//};
//
//
//int main()
//{
//	// C++98⽀持的
//	int a1[] = { 1, 2, 3, 4, 5 };
//	int a2[5] = { 0 };
//	Point p = { 1, 2 };
//
//	//C++98的
//	int x = 1;
//	// C++11⽀持的
//	//内置类型
//	int x1 = { 2 };
//	int x2{ 3 };
//
//	//C++98自定义类型初始化
//	Date d(2025, 1, 1);
//	// C++11⾃定义类型⽀持
//	// 这⾥本质是⽤{ 2025, 1, 1}构造⼀个Date临时对象
//	// 临时对象再去拷⻉构造d1，编译器优化后合⼆为⼀变成{ 2025, 1, 1}直接构造初始化
//	// 运⾏⼀下，我们可以验证上⾯的理论，发现是没调⽤拷⻉构造的
//	Date d1 = { 2025, 1, 1 };
//
//	// 这⾥d2引⽤的是{ 2024, 7, 25 }构造的临时对象
//	const Date& d2 = { 2024, 7, 25 };
//
//	// 需要注意的是C++98⽀持单参数时类型转换，也可以不⽤{}
//	Date d3 = { 2025 };
//	Date d4 = 2025;
//	// 可以省略掉=
//	Point p1{ 1, 2 };
//	int x3{ 2 };
//	Date d6{ 2024, 7, 25 };
//	const Date& d7{ 2024, 7, 25 };
//	// 不⽀持，只有{}初始化，才能省略=
//	// Date d8 2025;
//	vector<Date> v;
//	v.push_back(d1);
//	v.push_back(Date(2025, 1, 1));
//	// ⽐起有名对象和匿名对象传参，这⾥{}更有性价⽐
//	v.push_back({ 2025, 1, 1 });
//
//	//这里的{}调用的是构造多参数的构造
//	Date dd{ 2025,1,1 };
//	//这里是先构造initializer_list,再调用vector实现的initializer_list构造函数
//	vector<int> v1 = { 1,2,3,4,5 };
//
//	auto il = { 1,2,3,4,5 };
//	cout << sizeof(il) << endl;
//	cout << typeid(il).name() << endl;
//	int x = 10;  // x是左值，存储在栈上，有持久地址
//	int* p = &x; // 合法：可获取x的地址
//	     // 合法：可通过地址修改左值
//
//	return 0;
//}


//int main()
//{
//	int x = 10;
//	int* px = &x;
//	*px = 20;
//	return 0;
//}
//
//#include<iostream>
//#include<vector>
//#include<string>
//
//using namespace std;

//int main()
//{
//	//左值引用：给左值取别名
//	int x = 10;
//	int& y = x;
//
//	//右值引用：给右值取别名
//	int&& a = 10;
//
//	int&& b = move(x);
//
//
//	return 0;
//}
//void f(int& x)
//{
//	std::cout << "左值引用重载 f(" << x << ")\n";
//}
//void f(const int& x)
//{
//	std::cout << "到 const 的左值引用重载 f(" << x << ")\n";
//}
//void f(int&& x)
//{
//	std::cout << "右值引用重载 f(" << x << ")\n";
//}
//int main()
//{
//	int i = 1;
//	const int ci = 2;
//	f(i); // 调⽤ f(int&)
//	f(ci); // 调⽤ f(const int&)
//	f(3); // 调⽤ f(int&&)，如果没有 f(int&&) 重载则会调⽤ f(const int&)
//	f(std::move(i)); // 调⽤ f(int&&)
//	// 右值引⽤变量在⽤于表达式时是左值
//	int&& x = 1;
//	f(x); // 调⽤ f(int& x)
//	f(std::move(x)); // 调⽤ f(int&& x)
//	return 0;
//}
//
//int main()
//{
//	std::string s1 = "Test";
//	// std::string&& r1 = s1; // 错误：不能绑定到左值
//	const std::string& r2 = s1 + s1; // OK：到 const 的左值引⽤延⻓⽣存期
//	// r2 += "Test"; // 错误：不能通过到 const 的引⽤修改
//	std::string&& r3 = s1 + s1; // OK：右值引⽤延⻓⽣存期
//	//右值被右值引用后表达式的属性就变成了左值
//	r3 += "Test"; // OK：能通过到⾮ const 的引⽤修改
//	std::cout << r3 << '\n';
//	return 0;
//}

//
//string(const string& s)
//	:_str(nullptr)
//{
//	cout << "string(const string& s) -- 拷⻉构造" << endl;
//
//	reserve(s._capacity);
//	for (auto ch : s)
//	{
//		push_back(ch);
//	}
//}

// 移动构造
//string(string&& s)
//{
//	cout << "string(string&& s) -- 移动构造" << endl;
//	swap(s);
//}

//string& operator=(const string& s)
//{
//	cout << "string& operator=(const string& s) -- 拷⻉赋值" <<
//		endl;
//	if (this != &s)
//	{
//		_str[0] = '\0';
//		_size = 0;
//		reserve(s._capacity);
//		for (auto ch : s)
//		{
//			push_back(ch);
//		}
//	}
//	return *this;
//}

//string& operator=(string&& s)
//{
//	cout << "string& operator=(string&& s) -- 移动赋值" << endl;
//	swap(s);
//	return *this;
//}


#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
#include<string.h>
#include<algorithm>
#include<list>
using namespace std;
namespace wx
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)-构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) -- 拷贝构造" << endl;
			reserve(s._capacity);
			for (auto ch : s)
			{
				push_back(ch);
			}
		}
		// 移动构造
		string(string&& s)
		{
			cout << "string(string&& s) -- 移动构造" << endl;
			swap(s);
		}
		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) -- 拷⻉赋值" <<
				endl;
			if (this != &s)
			{
				_str[0] = '\0';
				_size = 0;
				reserve(s._capacity);
				for (auto ch : s)
				{
					push_back(ch);
				}
			}
			return *this;
		}
		// 移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
			swap(s);
			return *this;
		}
		~string()
		{
			//cout << "~string() -- 析构" << endl;
			delete[] _str;
			_str = nullptr;
		}
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				if (_str)
				{
					strcpy(tmp, _str);
					delete[] _str;
				}
				_str = tmp;
				_capacity = n;
			}
		}
		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity *
					2;
				reserve(newcapacity);
			}
			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		const char* c_str() const
		{
			return _str;
		}
		size_t size() const
		{
			return _size;
		}
	private:
		char* _str = nullptr;
		size_t _size = 0;
		size_t _capacity = 0;
	};

	template<class T>
	struct ListNode
	{
		ListNode<T>* _next;
		ListNode<T>* _prev;
		T _data;
		ListNode(const T& data = T())
			:_next(nullptr)
			, _prev(nullptr)
			, _data(data)
		{
		}
		ListNode(T&& data)
			:_next(nullptr)
			, _prev(nullptr)
			, _data(move(data))
		{
		}
	};
	template<class T, class Ref, class Ptr>
	struct ListIterator
	{
		typedef ListNode<T> Node;
		typedef ListIterator<T, Ref, Ptr> Self;
		Node* _node;
		ListIterator(Node* node)
			:_node(node)
		{
		}
		Self& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		Ref operator*()
		{
			return _node->_data;
		}
		bool operator!=(const Self & it)
		{
			return _node != it._node;
		}
	};
	template<class T>
	class list
	{
		typedef ListNode<T> Node;
	public:
		typedef ListIterator<T, T&, T*> iterator;
		typedef ListIterator<T, const T&, const T*> const_iterator;
		iterator begin()
		{
			return iterator(_head->_next);
		}
		iterator end()
		{
			return iterator(_head);
		}
		void empty_init()
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;
		}
		list()
		{
			empty_init();
		}
		void push_back(const T& x)
		{
			insert(end(), x);
		}
		void push_back(T&& x)
		{
			insert(end(), move(x));
		}
		iterator insert(iterator pos, const T& x)
		{
		Node * cur = pos._node;
		Node* newnode = new Node(x);
		Node* prev = cur->_prev;
		// prev newnode cur
		prev->_next = newnode;
		newnode->_prev = prev;
		newnode->_next = cur;
		cur->_prev = newnode;
		return iterator(newnode);
		}
			iterator insert(iterator pos, T&& x)
		{
			Node* cur = pos._node;
			Node* newnode = new Node(move(x));
			Node* prev = cur->_prev;
			// prev newnode cur
			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;
			return iterator(newnode);
		}
	private:
		Node* _head;
	};
}
//int main()
//{
//	wx::string s1("xxxxx");
//	// 拷⻉构造
//	wx::string s2 = s1;
//	// 构造+移动构造，优化后直接构造
//	wx::string s3 = wx::string("yyyyy");
//	// 移动构造
//	wx::string s4 = move(s1);
//	cout << "******************************" << endl;
//	return 0;
//}


namespace wx
{
	string addStrings(string num1, string num2)
	{
		string str;
		int end1 = num1.size() - 1, end2 = num2.size() - 1;
		int next = 0;
		while (end1 >= 0 || end2 >= 0)
		{
			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
			int ret = val1 + val2 + next;
			next = ret / 10;
			ret = ret % 10;
			str += ('0' + ret);
		}
		if (next == 1)
			str += '1';
		reverse(str.begin(), str.end());
		cout << "******************************" << endl;
		return str;
	}
}
//// 场景1
//int main()
//{
//	wx::string ret = wx::addStrings("11111", "2222");
//	cout << ret.c_str() << endl;
//	return 0;
//}
// 场景2
//int main()
//{
//	wx::string ret;
//	ret = wx::addStrings("11111", "2222");
//	cout << ret.c_str() << endl;
//	return 0;
//}

//int main()
//{
//	//左值
//	std::list<wx::string> lt;
//	wx::string s1("111111111111111111111");
//	lt.push_back(s1);
//	//右值
//	cout << "*************************" << endl;
//	lt.push_back(wx::string("22222222222222222222222222222"));
//	cout << "*************************" << endl;
//	lt.push_back("3333333333333333333333333333");
//	cout << "*************************" << endl;
//	lt.push_back(move(s1));
//	cout << "*************************" << endl;
//	return 0;
//}

//int main()
//{
//	wx::list<wx::string> lt;
//	cout << "*************************" << endl;
//	wx::string s1("111111111111111111111");
//	lt.push_back(s1);
//	cout << "*************************" << endl;
//	lt.push_back(wx::string("22222222222222222222222222222"));
//	cout << "*************************" << endl;
//	lt.push_back("3333333333333333333333333333");
//	cout << "*************************" << endl;
//	lt.push_back(move(s1));
//	cout << "*************************" << endl;
//	return 0;
//}

//int main()
//{
//	typedef int& lref;
//	typedef int&& rref;
//	int n = 0;
//	lref& r1 = n; // r1 的类型是 int&
//	lref&& r2 = n; // r2 的类型是 int&
//	rref& r3 = n; // r3 的类型是 int&
//	rref&& r4 = 1; // r4 的类型是 int&&
//
//	return 0;
//}

//template<class T>
//void f1(T& x)
//{
//}
//// 由于引⽤折叠限定，f2实例化后可以是左值引⽤，也可以是右值引⽤
//template<class T>
//void f2(T&& x)
//{
//}
//int main()
//{
//	typedef int& lref;
//	typedef int&& rref;
//	int n = 0;
//	lref& r1 = n; // r1 的类型是 int&
//	lref&& r2 = n; // r2 的类型是 int&
//	rref& r3 = n; // r3 的类型是 int&
//	rref&& r4 = 1; // r4 的类型是 int&&
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	f1<int>(0); // 报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	f1<int&>(0); // 报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	f1<int&&>(0); // 报错
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0);
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//		f1<const int&&>(0);
//	// 没有折叠->实例化为void f2(int&& x)
//	f2<int>(n); // 报错
//	f2<int>(0);
//	// 折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	f2<int&>(0); // 报错
//	// 折叠->实例化为void f2(int&& x)
//	f2<int&&>(n); // 报错
//	f2<int&&>(0);
//	return 0;
//}

template<class T>
void Function(T&& t)
{
	int a = 0;
	T x = a;
	//x++;
	cout << &a << endl;
	cout << &x << endl << endl;
}
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//	int a;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//	const int b = 8;
//	// a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int&t)
//	// 所以Function内部会编译报错，x不能++
//	Function(b); // const 左值
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&&t)
//	// 所以Function内部会编译报错，x不能++
//	Function(std::move(b)); // const 右值
//	return 0;
//}

//template <class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;
//}
//// 原理1：编译本质这⾥会结合引⽤折叠规则实例化出以下四个函数
//void Print();
//void Print(int&& arg1);
//void Print(int&& arg1, string&& arg2);
//void Print(double&& arg1, string&& arg2, double& arg3);
//int main()
//{
//	double x = 2.2;
//	Print(); // 包⾥有0个参数
//	Print(1); // 包⾥有1个参数
//	Print(1, string("xxxxx")); // 包⾥有2个参数
//	Print(1.1, string("xxxxx"), x); // 包⾥有3个参数
//	return 0;
//}

//int main()
//{
//	list<wx::string> lt;
//	// 传左值，跟push_back⼀样，⾛拷⻉构造
//	wx::string s1("111111111111");
//	lt.emplace_back(s1);
//	cout << "*********************************" << endl;
//	// 右值，跟push_back⼀样，⾛移动构造
//	lt.emplace_back(move(s1));
//	cout << "*********************************" << endl;
//	// 直接把构造string参数包往下传，直接⽤string参数包构造string
//	// 这⾥达到的效果是push_back做不到的
//	lt.emplace_back("111111111111");
//	cout << "*********************************" << endl;
//	list<pair<wx::string, int>> lt1;
//	// 跟push_back⼀样
//	// 构造pair + 拷⻉/移动构造pair到list的节点中data上
//	pair<wx::string, int> kv("苹果", 1);
//	lt1.emplace_back(kv);
//	cout << "*********************************" << endl;
//	// 跟push_back⼀样
//	lt1.emplace_back(move(kv));
//	cout << "*********************************" << endl;
//	////////////////////////////////////////////////////////////////////
//	// 直接把构造pair参数包往下传，直接⽤pair参数包构造pair
//	// 这⾥达到的效果是push_back做不到的
//	lt1.emplace_back("苹果", 1);
//	cout << "*********************************" << endl;
//	return 0;
//}

class Person
{
public:
	Person(const char* name = "", int age = 0)
		:_name(name)
		, _age(age)
	{
	}
	/*Person(const Person& p)
	:_name(p._name)
	,_age(p._age)
	{}*/
	/*Person& operator=(const Person& p)
	{
	if(this != &p)
	{
	_name = p._name;
	_age = p._age;
	}
	return *this;
	}*/

		/*~Person()
		{}*/
private:
	wx::string _name;
	int _age;
};
//int main()
//{
//	Person s1;
//	Person s2 = s1;
//	Person s3 = std::move(s1);
//	Person s4;
//	s4 = std::move(s2);
//	return 0;
//}

//int main()
//{
//	// ⼀个简单的lambda表达式
//	auto add1 = [](int x, int y)->int {return x + y; };
//	cout << add1(1, 2) << endl;
//	// 1、捕捉为空也不能省略
//	// 2、参数为空可以省略
//	// 3、返回值可以省略，可以通过返回对象⾃动推导
//	// 4、函数题不能省略
//	auto func1 = []
//		{
//			cout << "hello bit" << endl;
//			return 0;
//		};
//	func1();
//	int a = 0, b = 1;
//	auto swap1 = [](int& x, int& y)
//		{
//			int tmp = x;
//			x = y;
//			y = tmp;
//		};
//	swap1(a, b);
//	cout << a << ":" << b << endl;
//	return 0;
//}

int x = 0;
// 捕捉列表必须为空，因为全局变量不⽤捕捉就可以⽤，没有可被捕捉的变量
auto func1 = []()
	{
		x++;
	};
int main()
{
	// 只能⽤当前lambda局部域和捕捉的对象和全局对象
	int a = 0, b = 1, c = 2, d = 3;
	auto func1 = [a, &b]
		{
			// 值捕捉的变量不能修改，引⽤捕捉的变量可以修改
			//a++;
			b++;
			int ret = a + b;
			return ret;
		};
	cout << func1() << endl;
	// 隐式值捕捉
	// ⽤了哪些变量就捕捉哪些变量
	auto func2 = [=]
		{
			int ret = a + b + c;
			return ret;
		};
	cout << func2() << endl;
	// 隐式引⽤捕捉
	// ⽤了哪些变量就捕捉哪些变量
	auto func3 = [&]
		{
			a++;
			c++;
			d++;
		};
	func3();
	cout << a << " " << b << " " << c << " " << d << endl;
	// 混合捕捉1
	auto func4 = [&, a, b]
		{
			//a++;
			//b++;
			c++;
			d++;
			return a + b + c + d;
		};
	func4();
	cout << a << " " << b << " " << c << " " << d << endl;
	// 混合捕捉1
	auto func5 = [=, &a, &b]
		{
			a++;
			b++;
			/*c++;
			d++;*/
			return a + b + c + d;
		};
	func5();
	cout << a << " " << b << " " << c << " " << d << endl;
	// 局部的静态和全局变量不能捕捉，也不需要捕捉
	static int m = 0;
	auto func6 = []
		{
			int ret = x + m;
			return ret;
		};
	// 传值捕捉本质是⼀种拷⻉,并且被const修饰了
	// mutable相当于去掉const属性，可以修改了
	// 但是修改了不会影响外⾯被捕捉的值，因为是⼀种拷⻉
	auto func7 = [=]()mutable
		{
			a++;
			b++;
			c++;
			d++;
			return a + b + c + d;
		};
	cout << func7() << endl;
	cout << a << " " << b << " " << c << " " << d << endl;
	return 0;
}